package org.jsea.meta.api.service;

import lombok.SneakyThrows;
import org.jsea.meta.api.service.dialect.AbstractMetaApiDialect;
import org.jsea.meta.api.service.dialect.IMetaApiDialect;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * --.
 * *
 * author   Jiang.hy
 * create   2022-04-14
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "meta-api.enabled", matchIfMissing = true)
public class MetaApiApplicationContext {

    @Bean
    public MetaApiAccessHandler metaApiAccessHandler(ApplicationContext context) {
        MetaApiProperties properties = context.getBean(MetaApiProperties.class);
        MetaApiAccessHandler handler = new MetaApiAccessHandler(properties.getRoute());
        handler.verifypermissions(properties.getVerifyAction(), properties.getPrimaryKey());
        return handler;
    }

    @Bean
    public MetaApiProcessor metaApiProcessor(MetaApiAccessHandler handler) {
        return new MetaApiProcessor(handler);
    }

    @SneakyThrows
    @Bean
    public IMetaApiDialect iMetaApiDialect(ApplicationContext context) {
        MetaApiProperties properties = context.getBean(MetaApiProperties.class);
        Class<? extends IMetaApiDialect> dbDialect = properties.getDbDialect();
        if (dbDialect == null) {
            DataSource dataSource = context.getBean(DataSource.class);
            try (Connection con = dataSource.getConnection()) {
                return AbstractMetaApiDialect.builder(con.getMetaData().getDatabaseProductName());
            }
        } else {
            try {
                return context.getBean(dbDialect);
            } catch (Exception ignored) {
                return BeanUtils.instantiateClass(dbDialect);
            }
        }
    }
}
